package com.cinc.ebc.mm.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cinc.ebc.mm.model.MmRptMaterialStockWarehouseStatModel;
import com.cinc.ebc.mm.model.MmRptStockInOutStatModel;
import com.cinc.ebc.mm.service.IMmStockInOutService;
import com.cinc.ebc.mm.entity.MmStockInOut;
import com.cinc.ebc.mm.entity.MmStockInOutDetail;
import com.cinc.ebc.mm.model.MmStockInOutDetailModel;
import com.cinc.ebc.mm.service.IMmStockInOutDetailService;
import com.cinc.ebc.mm.vo.MmRptMaterialStockStatPage;
import com.cinc.ebc.mm.vo.MmRptStockInOutStatPage;
import com.cinc.ebc.mm.vo.MmStockInOutDetailPage;
import com.cinc.ebc.mm.vo.MmStockInOutPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.aspect.annotation.PermissionData;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

 /**
 * @Description: 库存单据
 * @Author: jeecg-boot
 * @Date:   2022-04-05
 * @Version: V1.0
 */
@Api(tags="库存单据")
@RestController
@RequestMapping("/mm/stockInOut")
@Slf4j
public class MmStockInOutController {
	@Autowired
	private IMmStockInOutService mmStockInOutService;
	@Autowired
	private IMmStockInOutDetailService mmStockInOutDetailService;

	/**
	 * 分页列表查询
	 *
	 * @param mmStockInOut
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "库存单据-分页列表查询")
	@ApiOperation(value="库存单据-分页列表查询", notes="库存单据-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(MmStockInOut mmStockInOut,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<MmStockInOut> queryWrapper = QueryGenerator.initQueryWrapper(mmStockInOut, req.getParameterMap());
		Page<MmStockInOut> page = new Page<MmStockInOut>(pageNo, pageSize);
		IPage<MmStockInOut> pageList = mmStockInOutService.page(page, queryWrapper);
		return Result.OK(pageList);
	}

	 /**
	  * 明细分页列表查询
	  *
	  * @param detailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "库存单据明细-分页列表查询")
	 @ApiOperation(value="库存单据明细-分页列表查询", notes="库存单据明细-分页列表查询")
	 @GetMapping(value = "/detailPageList")
	 public Result<?> queryDetailPageList(MmStockInOutDetailPage detailPage,
									@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
									HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.detaiPage(page, detailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 明细列表查询
	  *
	  * @param detailPage
	  * @return
	  */
	 @AutoLog(value = "库存单据明细-分页列表查询")
	 @ApiOperation(value="库存单据明细-分页列表查询", notes="库存单据明细-分页列表查询")
	 @GetMapping(value = "/detailList")
	 public Result<?> queryDetailList(MmStockInOutDetailPage detailPage) {
		 List<MmStockInOutDetailModel> dataList = mmStockInOutService.detailList(detailPage);
		 return Result.OK(dataList);
	 }

	 /**
	  * 其它入库分页列表查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @PermissionData(pageComponent = "ebc/mm/MmOtherInList")
	 @AutoLog(value = "其它入库-分页列表查询")
	 @ApiOperation(value="其它入库-分页列表查询", notes="其它入库-分页列表查询")
	 @GetMapping(value = "/otherInList")
	 public Result<?> queryPageOtherInList(MmStockInOutDetailPage mmStockInOutDetailPage,
									@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
									HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.otherInPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 其它出库分页列表查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @PermissionData(pageComponent = "ebc/mm/MmOtherOutList")
	 @AutoLog(value = "其它出库-分页列表查询")
	 @ApiOperation(value="其它出库-分页列表查询", notes="其它出库-分页列表查询")
	 @GetMapping(value = "/otherOutList")
	 public Result<?> queryPageOtherOutList(MmStockInOutDetailPage mmStockInOutDetailPage,
										   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
										   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
										   HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.otherOutPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 盘盈入库查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @PermissionData(pageComponent = "ebc/mm/MmInventoryProfitList")
	 @AutoLog(value = "盘盈入库-分页列表查询")
	 @ApiOperation(value="盘盈入库-分页列表查询", notes="盘盈入库-分页列表查询")
	 @GetMapping(value = "/inventoryProfitList")
	 public Result<?> queryPageInventoryProfitList(MmStockInOutDetailPage mmStockInOutDetailPage,
											@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
											@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
											HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.inventoryProfitPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 盘亏出库查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @PermissionData(pageComponent = "ebc/mm/MmInventoryLossList")
	 @AutoLog(value = "盘亏出库-分页列表查询")
	 @ApiOperation(value="盘亏出库-分页列表查询", notes="盘亏出库-分页列表查询")
	 @GetMapping(value = "/inventoryLossList")
	 public Result<?> queryPageInventoryLossList(MmStockInOutDetailPage mmStockInOutDetailPage,
												   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
												   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
												   HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.inventoryLossPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 采购入库分页列表查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "采购入库-分页列表查询")
	 @ApiOperation(value="采购入库-分页列表查询", notes="采购入库-分页列表查询")
	 @GetMapping(value = "/purchaseInList")
	 public Result<?> queryPagePurchaseInList(MmStockInOutDetailPage mmStockInOutDetailPage,
											  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
											  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
											  HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.purchaseInPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 采购退货分页列表查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "采购退货-分页列表查询")
	 @ApiOperation(value="采购退货-分页列表查询", notes="采购退货-分页列表查询")
	 @GetMapping(value = "/purchaseBackList")
	 public Result<?> queryPagePurchaseBackList(MmStockInOutDetailPage mmStockInOutDetailPage,
											  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
											  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
											  HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.purchaseBackPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	 /**
	  * 出入库流水查询
	  *
	  * @param mmStockInOutDetailPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "出入库流水查询")
	 @ApiOperation(value="出入库流水查询", notes="出入库流水查询")
	 @GetMapping(value = "/rptList")
	 public Result<?> queryPageRptList(MmStockInOutDetailPage mmStockInOutDetailPage,
											  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
											  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
											  HttpServletRequest req) {
		 Page<MmStockInOutDetailModel> page = new Page<>(pageNo, pageSize);
		 mmStockInOutService.rptPage(page, mmStockInOutDetailPage);
		 return Result.OK(page);
	 }

	/**
	 *   添加
	 *
	 * @param mmStockInOutPage
	 * @return
	 */
	@AutoLog(value = "库存单据-添加")
	@ApiOperation(value="库存单据-添加", notes="库存单据-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody MmStockInOutPage mmStockInOutPage) throws Exception {
		MmStockInOut mmStockInOut = new MmStockInOut();
		BeanUtils.copyProperties(mmStockInOutPage, mmStockInOut);
		mmStockInOutService.saveMain(mmStockInOut, mmStockInOutPage.getMmStockInOutDetailList(), false);
		return Result.OK("添加成功！");
	}

	 /**
	  *  添加采购入库单
	  *
	  * @param mmStockInOutPage
	  * @return
	  */
	 @AutoLog(value = "采购入库单-添加")
	 @ApiOperation(value="采购入库单-添加", notes="采购入库单-添加")
	 @PostMapping(value = "/addPurchaseIn")
	 public Result<?> addPurchaseIn(@RequestBody MmStockInOutPage mmStockInOutPage) throws Exception {
		 MmStockInOut mmStockInOut = new MmStockInOut();
		 BeanUtils.copyProperties(mmStockInOutPage, mmStockInOut);
		 mmStockInOutService.saveMainPurchaseIn(mmStockInOut, mmStockInOutPage.getMmStockInOutDetailList());
		 return Result.OK("添加成功！");
	 }

	 /**
	  *   添加采购退货单
	  *
	  * @param mmStockInOutPage
	  * @return
	  */
	 @AutoLog(value = "添加采购退货单-添加")
	 @ApiOperation(value="添加采购退货单-添加", notes="添加采购退货单-添加")
	 @PostMapping(value = "/addPurchaseBack")
	 public Result<?> addPurchaseBack(@RequestBody MmStockInOutPage mmStockInOutPage) throws Exception {
		 MmStockInOut mmStockInOut = new MmStockInOut();
		 BeanUtils.copyProperties(mmStockInOutPage, mmStockInOut);
		 mmStockInOutService.saveMainPurchaseBack(mmStockInOut, mmStockInOutPage.getMmStockInOutDetailList());
		 return Result.OK("添加成功！");
	 }

	 /**
	  *  盘盈入库
	  *
	  * @param mmStockInOutPage
	  * @return
	  */
	 @AutoLog(value = "盘盈入库-添加")
	 @ApiOperation(value="盘盈入库-添加", notes="盘盈入库-添加")
	 @PostMapping(value = "/addInventoryProfit")
	 public Result<?> addInventoryProfit(@RequestBody MmStockInOutPage mmStockInOutPage) throws Exception {
		 MmStockInOut mmStockInOut = new MmStockInOut();
		 BeanUtils.copyProperties(mmStockInOutPage, mmStockInOut);
		 mmStockInOutService.saveMainInventoryProfit(mmStockInOut, mmStockInOutPage.getMmStockInOutDetailList());
		 return Result.OK("添加成功！");
	 }

	 /**
	  *  盘亏出库
	  *
	  * @param mmStockInOutPage
	  * @return
	  */
	 @AutoLog(value = "盘亏出库-添加")
	 @ApiOperation(value="盘亏出库-添加", notes="盘盈入库-添加")
	 @PostMapping(value = "/addInventoryLoss")
	 public Result<?> addInventoryLoss(@RequestBody MmStockInOutPage mmStockInOutPage) throws Exception {
		 MmStockInOut mmStockInOut = new MmStockInOut();
		 BeanUtils.copyProperties(mmStockInOutPage, mmStockInOut);
		 mmStockInOutService.saveMainInventoryLoss(mmStockInOut, mmStockInOutPage.getMmStockInOutDetailList());
		 return Result.OK("添加成功！");
	 }

	/**
	 *  编辑
	 *
	 * @param mmStockInOutPage
	 * @return
	 */
	@AutoLog(value = "库存单据-编辑")
	@ApiOperation(value="库存单据-编辑", notes="库存单据-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody MmStockInOutPage mmStockInOutPage) {
		MmStockInOut mmStockInOut = new MmStockInOut();
		BeanUtils.copyProperties(mmStockInOutPage, mmStockInOut);
		MmStockInOut mmStockInOutEntity = mmStockInOutService.getById(mmStockInOut.getId());
		if(mmStockInOutEntity==null) {
			return Result.error("未找到对应数据");
		}
		mmStockInOutService.updateMain(mmStockInOut, mmStockInOutPage.getMmStockInOutDetailList());
		return Result.OK("编辑成功!");
	}

	 /**
	  *  单据冲销
	  *
	  * @param detailPageList
	  * @return
	  */
	 @AutoLog(value = "单据冲销")
	 @ApiOperation(value="单据冲销", notes="单据冲销")
	 @PostMapping(value = "/writeOff")
	 public Result<?> writeOff(@RequestBody List<MmStockInOutDetailPage> detailPageList) throws Exception {
		 mmStockInOutService.writeOff(detailPageList);
		 return Result.OK("冲销成功！");
	 }

	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "库存单据-通过id删除")
	@ApiOperation(value="库存单据-通过id删除", notes="库存单据-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		mmStockInOutService.delMain(id);
		return Result.OK("删除成功!");
	}

	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "库存单据-批量删除")
	@ApiOperation(value="库存单据-批量删除", notes="库存单据-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.mmStockInOutService.delBatchMain(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功！");
	}

	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "库存单据-通过id查询")
	@ApiOperation(value="库存单据-通过id查询", notes="库存单据-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		MmStockInOut mmStockInOut = mmStockInOutService.getById(id);
		if(mmStockInOut==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(mmStockInOut);

	}

	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "库存单据明细通过主表ID查询")
	@ApiOperation(value="库存单据明细主表ID查询", notes="库存单据明细-通主表ID查询")
	@GetMapping(value = "/queryMmStockInOutDetailByMainId")
	public Result<?> queryMmStockInOutDetailListByMainId(@RequestParam(name="id",required=true) String id) {
		List<MmStockInOutDetail> mmStockInOutDetailList = mmStockInOutDetailService.selectByMainId(id);
		return Result.OK(mmStockInOutDetailList);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param mmStockInOut
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, MmStockInOut mmStockInOut) {
      // Step.1 组装查询条件查询数据
      QueryWrapper<MmStockInOut> queryWrapper = QueryGenerator.initQueryWrapper(mmStockInOut, request.getParameterMap());
      LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

      //Step.2 获取导出数据
      List<MmStockInOut> queryList = mmStockInOutService.list(queryWrapper);
      // 过滤选中数据
      String selections = request.getParameter("selections");
      List<MmStockInOut> mmStockInOutList = new ArrayList<MmStockInOut>();
      if(oConvertUtils.isEmpty(selections)) {
          mmStockInOutList = queryList;
      }else {
          List<String> selectionList = Arrays.asList(selections.split(","));
          mmStockInOutList = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
      }

      // Step.3 组装pageList
      List<MmStockInOutPage> pageList = new ArrayList<MmStockInOutPage>();
      for (MmStockInOut main : mmStockInOutList) {
          MmStockInOutPage vo = new MmStockInOutPage();
          BeanUtils.copyProperties(main, vo);
          List<MmStockInOutDetail> mmStockInOutDetailList = mmStockInOutDetailService.selectByMainId(main.getId());
          vo.setMmStockInOutDetailList(mmStockInOutDetailList);
          pageList.add(vo);
      }

      // Step.4 AutoPoi 导出Excel
      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
      mv.addObject(NormalExcelConstants.FILE_NAME, "库存单据列表");
      mv.addObject(NormalExcelConstants.CLASS, MmStockInOutPage.class);
      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("库存单据数据", "导出人:"+sysUser.getRealname(), "库存单据"));
      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
      return mv;
    }

    /**
    * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
          MultipartFile file = entity.getValue();// 获取上传文件对象
          ImportParams params = new ImportParams();
          params.setTitleRows(2);
          params.setHeadRows(1);
          params.setNeedSave(true);
          try {
              List<MmStockInOutPage> list = ExcelImportUtil.importExcel(file.getInputStream(), MmStockInOutPage.class, params);
              for (MmStockInOutPage page : list) {
                  MmStockInOut po = new MmStockInOut();
                  BeanUtils.copyProperties(page, po);
                  mmStockInOutService.saveMain(po, page.getMmStockInOutDetailList());
              }
              return Result.OK("文件导入成功！数据行数:" + list.size());
          } catch (Exception e) {
              log.error(e.getMessage(),e);
              return Result.error("文件导入失败:"+e.getMessage());
          } finally {
              try {
                  file.getInputStream().close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      return Result.OK("文件导入失败！");
    }

	 /**
	  * 出入库统计
	  *
	  * @param mmRptStockInOutStatPage
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 @AutoLog(value = "出入库统计")
	 @ApiOperation(value="出入库统计", notes="出入库统计")
	 @GetMapping(value = "/rptStockInOutStatList")
	 public Result<?> queryRptStockInOutStatList(MmRptStockInOutStatPage mmRptStockInOutStatPage,
												 @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
												 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
												 HttpServletRequest req) {
		 Page<MmRptStockInOutStatModel> page = new Page<>(pageNo, pageSize);
		 IPage<MmRptStockInOutStatModel> pageList = mmStockInOutService.queryRptStockInOutStatList(page, mmRptStockInOutStatPage);
		 return Result.OK(pageList);
	 }
}
